﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SecTool.Core.Crypto;

namespace SecTool.Core.Test
{
    [Microsoft.VisualStudio.TestTools.UnitTesting.TestClass]
    public class ServiceTest
    {
        [Microsoft.VisualStudio.TestTools.UnitTesting.TestMethod]
        public void EncryptTest()
        {
            Document d = new Document();
            d.Algorithm = Crypto.SymmetricAlgorithm.AES;
            d.HashAlgorithm = Crypto.HashAlgorithm.MD5;
            d.Payload = new byte[] {
                (byte)'m',
                (byte)'e',
                (byte)'s',
                (byte)'s',
                (byte)'a',
                (byte)'g',
                (byte)'e',
            };
            d.Author = d.Recipient = "obrad";
            var e = Service.Encrypt(d);
            Assert.IsFalse(d.Payload.SequenceEqual(e.Payload));
        }

        [Microsoft.VisualStudio.TestTools.UnitTesting.TestMethod]
        public void EncryptDecryptTest()
        {
            Document d = new Document();
            d.Algorithm = Crypto.SymmetricAlgorithm.AES;
            d.HashAlgorithm = Crypto.HashAlgorithm.MD5;
            d.Payload = new byte[] {
                (byte)'m',
                (byte)'e',
                (byte)'s',
                (byte)'s',
                (byte)'a',
                (byte)'g',
                (byte)'e',
            };
            d.Author = d.Recipient = "obrad";
            var e = Service.Encrypt(d);
            Assert.IsFalse(d.Payload.SequenceEqual(e.Payload));
            var de = Service.Decrypt(e);
            Assert.IsTrue(d.Payload.SequenceEqual(de.Payload));
        }

        [Microsoft.VisualStudio.TestTools.UnitTesting.TestMethod]
        public void EncryptDecryptWrongKeyTest()
        {
            Document d = new Document();
            d.Algorithm = Crypto.SymmetricAlgorithm.AES;
            d.HashAlgorithm = Crypto.HashAlgorithm.MD5;
            d.Payload = new byte[] {
                (byte)'m',
                (byte)'e',
                (byte)'s',
                (byte)'s',
                (byte)'a',
                (byte)'g',
                (byte)'e',
            };
            d.Author = d.Recipient = "obrad";
            var e = Service.Encrypt(d);
            Assert.IsFalse(d.Payload.SequenceEqual(e.Payload));
            e.Recipient = "marko";
            try
            {
                var de = Service.Decrypt(e);
            }
            catch (Exception ex)
            {
                Assert.IsInstanceOfType(ex, typeof(System.Security.Cryptography.CryptographicException));
            }
        }

        [Microsoft.VisualStudio.TestTools.UnitTesting.TestMethod]
        public void SignTest()
        {
            Document d = new Document();
            d.Algorithm = Crypto.SymmetricAlgorithm.AES;
            d.HashAlgorithm = Crypto.HashAlgorithm.MD5;
            d.Payload = new byte[] {
                (byte)'m',
                (byte)'e',
                (byte)'s',
                (byte)'s',
                (byte)'a',
                (byte)'g',
                (byte)'e',
            };
            d.Author = d.Recipient = "obrad";
            var e = Service.Sign(d);
            Assert.IsNotNull(e.Signature);
        }

        [Microsoft.VisualStudio.TestTools.UnitTesting.TestMethod]
        public void SignVerifyTest()
        {
            Document d = new Document();
            d.Algorithm = Crypto.SymmetricAlgorithm.AES;
            d.HashAlgorithm = Crypto.HashAlgorithm.MD5;
            d.Payload = new byte[] {
                (byte)'m',
                (byte)'e',
                (byte)'s',
                (byte)'s',
                (byte)'a',
                (byte)'g',
                (byte)'e',
            };
            d.Author = d.Recipient = "obrad";
            var e = Service.Sign(d);
            Assert.IsNotNull(e.Signature);
            bool verified = Service.Verify(e);
            Assert.IsTrue(verified);
            e.Signature[0] = Convert.ToByte(e.Signature[0] ^ 0xFF);
            verified = Service.Verify(e);
            Assert.IsFalse(verified);
        }
    }
}